package com.mycontacts;

import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class ContactsDataSource {
	
	/*
	 * Private members
	 */
	private SQLiteDatabase db;
	private ContactsSQLiteHelper dbHelper;
	private String[] allColumns = { 
			ContactsSQLiteHelper.COLUMN_ID,
			ContactsSQLiteHelper.COLUMN_NAME,
			ContactsSQLiteHelper.COLUMN_ADDRESS,
			ContactsSQLiteHelper.COLUMN_CELL,
			ContactsSQLiteHelper.COLUMN_ALT,
			ContactsSQLiteHelper.COLUMN_EMAIL,
			ContactsSQLiteHelper.COLUMN_COMMENTS,
			ContactsSQLiteHelper.COLUMN_CAT1,
			ContactsSQLiteHelper.COLUMN_CAT2,
			ContactsSQLiteHelper.COLUMN_CAT3,
			ContactsSQLiteHelper.COLUMN_CAT4,
			ContactsSQLiteHelper.COLUMN_CAT5
			};
	
	/*
	 * Constructor
	 */
	public ContactsDataSource(Context context){
		dbHelper = new ContactsSQLiteHelper(context);
	}
	
	/*
	 * DB operations
	 */
	public void open() throws SQLException{
		db = dbHelper.getWritableDatabase();
	}
	
	public void close(){
		dbHelper.close();
	}
	
	/*
	 * Common queries
	 */
	
	//Returns all contacts
	private Cursor queryAll(){
		Cursor c = db.query(ContactsSQLiteHelper.TABLE_CONTACTS, allColumns, null, null, null, null, null);
		return c;
	}

	/*
	 * Add, update, delete operations
	 */
	public Contact addContact(
			String name,
			String address,
			String cell,
			String alt,
			String email,
			String comments,
			boolean cat1,
			boolean cat2,
			boolean cat3,
			boolean cat4,
			boolean cat5
			){
		
		//Prepare INSERT query, add column names and values
		ContentValues values = new ContentValues();
		values.put(ContactsSQLiteHelper.COLUMN_NAME,name);
		values.put(ContactsSQLiteHelper.COLUMN_ADDRESS,address);
		values.put(ContactsSQLiteHelper.COLUMN_CELL,cell);
		values.put(ContactsSQLiteHelper.COLUMN_ALT,alt);
		values.put(ContactsSQLiteHelper.COLUMN_EMAIL,email);
		values.put(ContactsSQLiteHelper.COLUMN_COMMENTS,comments);
		values.put(ContactsSQLiteHelper.COLUMN_CAT1,cat1);
		values.put(ContactsSQLiteHelper.COLUMN_CAT2,cat2);
		values.put(ContactsSQLiteHelper.COLUMN_CAT3,cat3);
		values.put(ContactsSQLiteHelper.COLUMN_CAT4,cat4);
		values.put(ContactsSQLiteHelper.COLUMN_CAT5,cat5);
		
		//INSERT into contacts table
		long insertId = db.insert(ContactsSQLiteHelper.TABLE_CONTACTS, null, values);
		
		//Get a cursor pointing to the newly created contact
		Cursor cursor = db.query(ContactsSQLiteHelper.TABLE_CONTACTS, allColumns, ContactsSQLiteHelper.COLUMN_ID + " = " + insertId, null, null, null, null);
		cursor.moveToFirst();
		
		Contact newContact = cursorToContact(cursor);
		
		cursor.close();
		
		return newContact;
	}
	
	//TODO implement contact update
	public Contact updateContact(Contact contact) throws Exception{
		throw new Exception("Not implemented");
	}
	
	//TODO implement contact delete
	public void deleteContact(Contact contact){
		long deleteId = contact.getId();
		
		int numRemoved = db.delete(ContactsSQLiteHelper.TABLE_CONTACTS, ContactsSQLiteHelper.COLUMN_ID + " = " + deleteId, null);
		if(numRemoved <= 0){
			Log.d("CM", "No contact removed!");
		}
	}
	
	public void deleteContact(long deleteId){
		int numRemoved = db.delete(ContactsSQLiteHelper.TABLE_CONTACTS, ContactsSQLiteHelper.COLUMN_ID + " = " + deleteId, null);
		if(numRemoved <= 0){
			Log.d("CM", "No contact removed!");
		}
	}
	
	/*
	 * Get methods
	 */
	public ArrayList<Contact> getAllContacts(){	
		Cursor cursor = queryAll();
		ArrayList<Contact> contacts = cursorToContactList(cursor);
		cursor.close();
		return contacts;
	}
	
	//TODO implement contact name search
	public ArrayList<Contact> getContactsByPartialName(String name) throws Exception{
		throw new Exception("Not implemented");
	}
	
	/*
	 * Conversion methods
	 */
	private Contact cursorToContact(Cursor cursor){
		Contact c = new Contact();
		c.setId(cursor.getLong(0));
		c.setName(cursor.getString(1));
		c.setAddress(cursor.getString(2));
		c.setCell(cursor.getString(3));
		c.setAlt(cursor.getString(4));
		c.setEmail(cursor.getString(5));
		c.setComments(cursor.getString(6));
		
		//Android SQLite implementation has no boolean?
		//http://stackoverflow.com/questions/4088080/android-sqlite-get-boolean-from-database
		c.setCat1(cursor.getInt(cursor.getInt(7))>0);
		c.setCat2(cursor.getInt(cursor.getInt(8))>0);
		c.setCat3(cursor.getInt(cursor.getInt(9))>0);
		c.setCat4(cursor.getInt(cursor.getInt(10))>0);
		c.setCat5(cursor.getInt(cursor.getInt(11))>0);
		
		return c;
	}
	
	private ArrayList<Contact> cursorToContactList(Cursor cursor){
		ArrayList<Contact> list = new ArrayList<Contact>();
		cursor.moveToFirst();
	    while (!cursor.isAfterLast()) {
	      Contact contact = cursorToContact(cursor);
	      list.add(contact);
	      cursor.moveToNext();
	    }
	    return list;
	}
}
